package cn.buildoncloud.labor.workermanapplet.business.modules.services.impl;

import cn.buildoncloud.labor.workermanapplet.business.modules.controller.EnterPersonCountByLaborService;
import cn.buildoncloud.labor.workermanapplet.business.modules.services.DataStatisticsService;
import cn.buildoncloud.labor.workermanapplet.business.modules.services.EquipmentService;
import cn.buildoncloud.labor.workermanapplet.business.modules.services.UserService;
import cn.buildoncloud.labor.workermanapplet.common.base.service.BaseServiceImpl;
import cn.buildoncloud.labor.workermanapplet.util.StringUtil;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Record;
import org.nutz.dao.sql.Sql;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Description: cn.buildoncloud.labor.workermanapplet.business.modules.services.impl
 * Created by CuiZibo on 2018/11/5 10:32
 */
@Service
public class DataStatisticsServiceImpl extends BaseServiceImpl<Map> implements DataStatisticsService {

    public DataStatisticsServiceImpl(Dao dao) {
        super(dao);
    }

    @Autowired
    private UserService userService;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private EquipmentService equipmentService;

    @Override
    public Map<String, Object> homePageIndex(String userId) {
        Map<String, Object> map = new HashMap<>();
        //拥有的项目ID
        List<String> projectIds = userService.getScopeProjectIds(userId);

        Map<String, Integer> projectNumData = queryProjectNumData(projectIds);
        Integer workerTeamNumData = queryWorkerTeamNumData(projectIds);
        Map<String, Integer> equipmentNumData = queryEquipmentNumData(projectIds);
        Integer workermanNum = queryWorkermanNumData(projectIds, 0);
        Integer workeringNum = queryWorkermanNumData(projectIds, 1);
        Integer attendanceManNum = queryAttendanceManNum(projectIds);
        List<Map> maps = queryProjectWorkerInfo(projectIds);

        //项目总数
        map.put("projectNumData", projectNumData);
        //在册班组
        map.put("workerTeamNumData", workerTeamNumData);
        //设备数量
        map.put("equipmentNumData", equipmentNumData);
        //注册工友
        map.put("workermanNum", workermanNum);
        //上工人数
        map.put("workeringNum", workeringNum);
        //实时出勤
        map.put("attendanceManNum", attendanceManNum);
        //在建项目相关数据
        map.put("projectWorkerInfoData", maps);

        return map;
    }

    //项目中人数详情
    private List<Map> queryProjectWorkerInfo(List<String> projectIds) {
        if (projectIds.size() < 1) {
            return new ArrayList<>();
        }
        StringBuffer sb = new StringBuffer();
        sb.append("SELECT t1.id, t1.`name`, IFNULL(t2.count_,0) count1, IFNULL(t3.count_,0) count2 FROM bi_project t1 LEFT JOIN ( SELECT t1.id projectId, COUNT(DISTINCT t2.worker_man_id) count_ FROM `bi_project` t1 LEFT JOIN bi_re_workman_and_teamproject t2 ON t1.id = t2.project_id and t2.workman_out_date is null GROUP BY t1.id) t2 ON t1.id = t2.projectId LEFT JOIN ( SELECT t1.id projectId, COUNT(DISTINCT t2.id) count_ FROM `bi_project` t1 LEFT JOIN bi_special_person t2 ON t1.id = t2.project_id WHERE t1.states = 1 AND t2.delFlag = FALSE GROUP BY t1.id) t3 ON t1.id = t3.projectId WHERE t1.states = 1 AND t1.id IN (@ids) ORDER BY count1 + count2 DESC ");
        Sql sql = Sqls.create(sb.toString());
        sql.setParam("ids", projectIds.toArray());
        sql.setCallback((conn, rs, sql1) -> {
            List<Map> list = new ArrayList<>();
            while (rs.next()) {
                Map map = new HashMap();
                map.put("id", rs.getLong("id") + "");
                map.put("name", rs.getString("name"));
                map.put("workemanNum", rs.getInt("count1"));
                map.put("otherPersonNum", rs.getInt("count2"));
                list.add(map);
            }
            return list;
        });
        dao().execute(sql);
        List<Map> list = sql.getList(Map.class);
        return list;
    }

    //出勤人数
    private Integer queryAttendanceManNum(List<String> projectIds) {
        int count = 0;
        if (projectIds.size() < 1) {
            return count;
        }
        for (String projectId : projectIds) {
            boolean b = this.tableIsExist("bi_attendance_record_", StringUtil.last2num(projectId));
            if (!b) {
                continue;
            }
            //TODO mongo中取进场人数
            count += queryAttendanceManNumByMongoDB(Long.parseLong(projectId));
        }
        return count;
    }

    //工友数
    private Integer queryWorkermanNumData(List<String> projectIds, int i) {
        if (projectIds.size() < 1) {
            return 0;
        }
        StringBuffer sb = new StringBuffer("SELECT COUNT(DISTINCT t1.worker_man_id) count FROM `bi_re_workman_and_teamproject` t1 WHERE t1.project_id IN (@ids) ");
        if (i == 1) {
            sb.append("AND t1.workman_out_date IS NULL");
        }
        Sql sql = Sqls.create(sb.toString());
        sql.setParam("ids", projectIds.toArray());
        List<Record> recordList = this.list(sql);

        return recordList.get(0).getInt("count");
    }

    //设备数
    private Map<String, Integer> queryEquipmentNumData(List<String> projectIds) {
        Map<String, Integer> map = new HashMap();
        if (projectIds.size() < 1) {
            map.put("num1", 0);
            map.put("num2", 0);
            return map;
        }
        Sql sql = Sqls.create("SELECT t2.unique_identity,t1.* FROM `re_equipment_and_project` t1 LEFT JOIN sys_equipment t2 ON t2.id = t1.equipment_id WHERE t1.project_id IN (@ids) AND t1.state = 0");
        sql.setParam("ids", projectIds.toArray());
        List<Record> recordList = this.list(sql);

        int num1 = 0;
        for (Record record : recordList) {
            String uniqueIdentity = record.getString("unique_identity");
            boolean b = equipmentService.isOnline(uniqueIdentity);
            if (b) num1++;
        }

        map.put("num1", num1);
        map.put("num2", recordList.size());

        return map;
    }

    //班组数
    private Integer queryWorkerTeamNumData(List<String> projectIds) {
        if (projectIds.size() < 1) {
            return 0;
        }
        Sql sql = Sqls.create("SELECT COUNT(DISTINCT t1.worker_team_id) team_num FROM `bi_re_workerteam_project` t1 where t1.project_id in (@proIds)");
        sql.setParam("proIds", projectIds.toArray());
        List<Record> list = this.list(sql);
        return list.get(0).getInt("team_num");

    }

    //项目数
    private Map<String, Integer> queryProjectNumData(List<String> projectIds) {
        Map<String, Integer> map = new HashMap<>();
        if (projectIds.size() < 1) {
            map.put("num1", 0);
            map.put("num2", 0);
            return map;
        }
        int num1 = dao().count("bi_project", Cnd.where("id", "in", projectIds.toArray()).and("approval_states", "=", 1).and("states", "=", 1));
        int num2 = dao().count("bi_project", Cnd.where("id", "in", projectIds.toArray()));
        map.put("num1", num1);
        map.put("num2", num2);
        return map;
    }

    @Override
    public Map<String, Object> projectIndex(String projectId) {
        Map<String, Object> map = new HashMap<>();

        Map workerManNumData = queryWorkerManNumByProject(projectId);

        Map otherManNumData = queryOtherManNumByProject(projectId);
        map.put("workerManNumData", workerManNumData);
        map.put("otherManNumData", otherManNumData);
        return map;
    }

    //项目总览  工友人数
    private Map queryWorkerManNumByProject(String projectId) {
        int inNum = 0;
        int allNum = 0;
        boolean b = this.tableIsExist("bi_attendance_record_", StringUtil.last2num(projectId));
        if (b) {
            inNum = queryAttendanceManNumByMongoDB(Long.parseLong(projectId));
        }
        allNum = dao().count("bi_re_workman_and_teamproject", Cnd.where("project_id", "=", projectId).and("workman_out_date", "is", null));
        Sql sql = Sqls.create("SELECT COUNT(DISTINCT worker_man_id) count FROM bi_re_workman_and_teamproject where project_id = @pid and workman_out_date is NULL");
        sql.setParam("pid", projectId);
        List<Record> recordList = this.list(sql);
        Map map = new HashMap();
        map.put("inNum", inNum);
        map.put("allNum", recordList.get(0).get("count"));
        return map;

    }

    //项目总览 工程人员人数
    private Map queryOtherManNumByProject(String projectId) {
        int count = dao().count("bi_special_person", Cnd.where("project_id", "=", projectId).and("delFlag", "=", false));
        Map map = new HashMap();
        map.put("inNum", count);
        map.put("allNum", 0);//未使用
        return map;

    }

    /**
     * 从mongo中查询实时进出工地得人数
     *
     * @param projectId
     * @return
     */
    public int queryAttendanceManNumByMongoDB(Long projectId) {

        Query q = Query.query(Criteria.where("projectId").is(projectId));
        EnterPersonCountByLaborService map = mongoTemplate.findOne(q, EnterPersonCountByLaborService.class);
        int i = 0;
        if (map != null) {
            Map<String, Map> data = map.getData();
            for (Map.Entry<String, Map> entry : data.entrySet()) {
                i += (int) entry.getValue().get("count");
            }
        }
        return i;
    }

}
